<?php
set_include_path("../include;include");
require_once '/util/globals.php';
require_once 'Database.php';
require_once '/model/Participant.php';
require_once '/model/Member.php';

/**
 * database access class for Participant
 *
 * @author Thomas Crepain <contact@thomascrepain.be>
 */
class ParticipantDAO
{
        const TABLENAME = 'participant';
        const PARTICIPANT_REGISTRATION_TABLENAME = 'participant_registration';

	/**
	 *
	 *
	 * @var Database
	 */
	private $db;

	/**
	 * Contains the Participant cache
	 *
	 * @var array
	 */
	private $memberCache = array();

	/**
	 * unique instance of this class
	 * Singleton pattern
	 *
	 * @var Database
	 */
	private static $uniqueInstance;


	/**
	 * constructs the DAO
	 */
	private function __construct()
	{
		// get database
                $this->db = Database::getInstance();
	}

	/**
	 * gets instance of database
	 *
	 * @return ParticipantDAO
	 */
	public static function getInstance()
	{
		if(!isset(self::$uniqueInstance))
		{
			self::$uniqueInstance = new self();
		}

		return self::$uniqueInstance;
	}

	/**
	 * Returns the firstname
	 *
	 * @return String
	 */
	public function getFirstnameByParticipantId(integer $participantId)
	{
		// build cache
		$this->buildCache($participantId);

		return $this->memberCache[$participantId]['firstname'];
	}


	/**
	 * Returns the lastname
	 *
	 * @return String
	 */
	public function getLastnameByParticipantId(integer $participantId)
	{
		// build cache
		$this->buildCache($participantId);

		return $this->memberCache[$participantId]['lastname'];
	}

        /**
	 * Returns the member id
	 *
	 * @return integer
	 */
	public function getMemberIdByParticipantId(integer $participantId)
	{
		// build cache
		$this->buildCache($participantId);

		return (integer) $this->memberCache[$memberId]['member_id'];
	}

        	/**
	 * Gives all the Particpant objects associated with this Registration (id)
         *
	 * @param integer $registrationId The id of the Registration in question
	 * @return An array of Participant objects
	 */
	public function getAllParticipantsByRegistrationId(integer $registrationId) {
            $participants = array();

            // Get all records for both id's
            $records = (array) $this->db->getRecords("SELECT p.participant_id, p.member_id, p.firstname, p.lastname
                                                FROM " . self::PARTICIPANT_REGISTRATION_TABLENAME . " AS pr
                                                INNER JOIN ".self::TABLENAME." AS p ON pr.participant_id = p.participant_id
                                                WHERE pr.registration_id = ?",
                                                array($registrationId));

            // for every retrieved record...
            foreach ($records as $record) {
                // Put every record in the cache
                $this->memberCache[$record['participant_id']] = $record;

                // Make a Participant object from every record
                $participant = Participant::createNew($record['firstname'], $record['lastname']);
                $participant->setId((integer) $record['participant_id']);
                if(!is_null($record['member_id'])) $participant->setMember(Member::loadMember((integer) $record['member_id']));

                $participants[] = $participant;
            }

            // Return an array of those Participant objects
            return $participants;
	}

	/**
	 * Build the cache for the participantId if needed
	 *
	 * @param integer	$participantId
	 */
	private function buildCache(integer $participantId)
	{
		// if cache is not build
		if(!isset($this->memberCache[$participantId]))
		{
                    // fill cache with this participant
                    $this->memberCache[$participantId] = $this->db->getRecord("SELECT p.participant_id, p.member_id, p.firstname, p.lastname
                                                                            FROM ".self::TABLENAME." AS p
                                                                            WHERE m.participant_id = ?",
                                                                            array($participantId));
		}
	}


        /**
         * Saves the given participant in the database
         *
         * @param Participant $participant
         * @return integer $id  id in database
         */
        public function save(Participant $participant){
            $id = 0;

            // is this a new participant?
            if(is_null($participant->getId())){
                $id = $this->db->insert(self::TABLENAME, array(
                        'firstname' => $participant->getFirstname(),
                        'lastname' => $participant->getLastname(),
                        'member_id' => (is_null($participant->getMember())) ? NULL : $participant->getMember()->getId()));
            } else {
                $id = $participant->getId();

                $this->db->update(self::TABLENAME, array(
                        'firstname' => $participant->getFirstname(),
                        'lastname' => $participant->getLastname(),
                        'member_id' => $participant->getMember()->getId()));
            }

            return $id;
        }
}

?>